package PrjHttpUtils

import (
	"dgo/goutils/utils"
	"gitee.com/ymofen/supervalue"
	"io"
	"net/http"
	"os"
	"sync/atomic"
	"time"
)

var (
	tick_run_flag  int32 = 0
	run_secs       int64 = 0
	defaultHttpSvr *http.Server
)

func GetRunSecs() int64 {
	return run_secs
}

func RunTicker() {
	if atomic.CompareAndSwapInt32(&tick_run_flag, 0, 1) {
		go func() {
			tick := time.NewTicker(time.Second)
			for {
				<-tick.C
				atomic.AddInt64(&run_secs, 1)
			}
		}()
	}
}

func CloseDefaultHttpSvr() {
	if defaultHttpSvr != nil {
		defaultHttpSvr.Close()
		defaultHttpSvr = nil
	}
}

func ResetHttpFunc() {
	http.DefaultServeMux = http.NewServeMux()
}

func ToHTTPError(err error) (msg string, httpStatus int) {
	if os.IsNotExist(err) {
		return "404 page not found", http.StatusNotFound
	}
	if os.IsPermission(err) {
		return "403 Forbidden", http.StatusForbidden
	}
	// Default:
	return "500 Internal Server Error", http.StatusInternalServerError
}

func ResponseAFile(w http.ResponseWriter, name string, isDirFunc func(f os.FileInfo)) {
	f, err := os.Open(name)
	if err != nil {
		msg, code := ToHTTPError(err)
		http.Error(w, msg, code)
		return
	}
	defer f.Close()

	d, err := f.Stat()
	if err != nil {
		msg, code := ToHTTPError(err)
		http.Error(w, msg, code)
		return
	}

	if d.IsDir() {
		if isDirFunc != nil {
			isDirFunc(d)
		} else {
			http.Error(w, "403 is directory", 403)
			return
		}
		return
	} else {
		//w.Header().Set("Content-Disposition", "attachment; filename=" + name)
		//w.Header().Set("Content-Type", http.DetectContentType(fileHeader))
		io.CopyN(w, f, d.Size())
	}
}

func StartHttpSvrFromConf2(conf *wrapper.SuperValue) bool {
	addr := conf.StringByPath("http.addr", "")
	if len(addr) > 0 {
		StartHttpSvr(addr)
		return true
	} else {
		return false
	}
}

func StartHttpSvrFromConfEx(conf *wrapper.SuperValue) bool {
	addr := conf.StringByPath("http.addr", "")
	if len(addr) > 0 {
		defaultHttpSvr = &http.Server{Addr: addr, Handler: nil}
		defaultHttpSvr.ReadTimeout = time.Second * 120 // 避免很多无用的连接不断开(ESTABLISHED)
		defaultHttpSvr.WriteTimeout = time.Second * 120
		sslfile := conf.StringByPath("http.ssl-certfile", "")
		if len(sslfile) > 0 {
			utils.Log.Infof("启动HTTPS服务:%s", addr)
			err := defaultHttpSvr.ListenAndServeTLS(sslfile, conf.StringByPath("http.ssl-keyfile", ""))
			if err != nil {
				utils.Log.Errf("启动HTTPS服务失败:%v", err)
			}
		} else {
			utils.Log.Infof("启动Http服务:%s", addr)
			err := defaultHttpSvr.ListenAndServe()
			if err != nil {
				utils.Log.Errf("启动Http服务失败:%v", err)
			}
		}

		defaultHttpSvr = nil
		return true
	} else {
		return false
	}
}

func StartHttpSvrWithHandler(caption, addr string, handler http.Handler) {
	defaultHttpSvr = &http.Server{Addr: addr, Handler: handler}
	defaultHttpSvr.ReadTimeout = time.Second * 120 // 避免很多无用的连接不断开(ESTABLISHED)
	defaultHttpSvr.WriteTimeout = time.Second * 120
	utils.Log.Infof("[%s]准备启动:%s", caption, addr)
	err := defaultHttpSvr.ListenAndServe()
	if err != nil {
		utils.Log.Errf("[%s]启动服务失败:%v", caption, err)
	}
	defaultHttpSvr = nil
}

func StartHttpSvr(addr string) {
	defaultHttpSvr = &http.Server{Addr: addr, Handler: nil}
	defaultHttpSvr.ReadTimeout = time.Second * 120 // 避免很多无用的连接不断开(ESTABLISHED)
	defaultHttpSvr.WriteTimeout = time.Second * 120

	utils.Log.Infof("启动Http服务:%s", addr)
	err := defaultHttpSvr.ListenAndServe()
	if err != nil {
		utils.Log.Errf("启动Http服务失败:%v", err)
	}
	defaultHttpSvr = nil
}

func CheckStartHttpSvrSSL(addr string, sslcertfile, sslkeyfile string) {
	defaultHttpSvr = &http.Server{Addr: addr, Handler: nil}
	defaultHttpSvr.ReadTimeout = time.Second * 120 // 避免很多无用的连接不断开(ESTABLISHED)
	defaultHttpSvr.WriteTimeout = time.Second * 120
	if len(sslcertfile) > 0 {
		utils.Log.Infof("启动HTTPS服务:%s", addr)
		err := defaultHttpSvr.ListenAndServeTLS(sslcertfile, sslkeyfile)
		if err != nil {
			utils.Log.Errf("启动Http服务失败:%v", err)
		}
	} else {
		utils.Log.Infof("启动HTTP服务:%s", addr)
		err := defaultHttpSvr.ListenAndServe()
		if err != nil {
			utils.Log.Errf("启动Http服务失败:%v", err)
		}
	}

	defaultHttpSvr = nil
}

func StartHttpSvrEx(caption, addr string) {
	defaultHttpSvr = &http.Server{Addr: addr, Handler: nil}
	defaultHttpSvr.ReadTimeout = time.Second * 120 // 避免很多无用的连接不断开(ESTABLISHED)
	defaultHttpSvr.WriteTimeout = time.Second * 120
	utils.Log.Infof("[%s]准备启动:%s", caption, addr)
	err := defaultHttpSvr.ListenAndServe()
	if err != nil {
		utils.Log.Errf("[%s]启动服务失败:%v", caption, err)
	}
	defaultHttpSvr = nil
}
